﻿using System;

public class TimePassed 
{
    private readonly string amount;
    
    public TimePassed(DateTime dt)
        : this(dt, dt.Kind)
    { }

    public TimePassed(DateTime dt, DateTimeKind kind)
    {
        double ms, secs, mins, hours, days, weeks, months, years;
 
        switch (kind)
        {
            case DateTimeKind.Unspecified:
            case DateTimeKind.Utc:
                ms = new TimeSpan(DateTime.UtcNow.Ticks - dt.Ticks).TotalMilliseconds;
                break;
            default:
                ms = new TimeSpan(DateTime.Now.Ticks - dt.Ticks).TotalMilliseconds;
                break;
        }

        var pluralize = new Func<double, string>(units =>
        {
            return (units >= 1 && units < 2) ? string.Empty : "s";
        });

        if ((secs = ms / 1000) < 1)
        {
            this.amount = ms + " ms";
        }
        else if ((mins = secs / 60) < 1)
        {
            this.amount = Math.Round(secs, 2) + " sec" + pluralize(secs);
        }
        else if ((hours = mins / 60) < 1)
        {
            this.amount = Math.Floor(mins) + " min" + pluralize(mins);
        }
        else if ((days = hours / 24) < 1)
        {
            this.amount = Math.Floor(hours) + " hour" + pluralize(hours);
        }
        else if ((weeks = days / 7) < 1)
        {
            this.amount = Math.Floor(days) + " day" + pluralize(days);
        }
        else if ((months = days / 30) < 1)
        {
            this.amount = Math.Floor(weeks) + " week" + pluralize(weeks);
        }
        else if ((years = days / 365) < 1)
        {
            this.amount = Math.Floor(months) + " month" + pluralize(months);
        }
        else
        {
            this.amount = Math.Floor(years) + " year" + pluralize(years);
        }

    }

    public override string ToString()
    {
        return this.amount + " ago";
    }

    public static implicit operator string(TimePassed timePassed)
    {
        if (timePassed == null)
        {
            throw new ArgumentNullException("timePassed");
        }

        return timePassed.ToString();
    }
}